#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <stdio.h>

#include "node.h"
#include "parser.h"
#include "errorlog.h"
#include "backend/javascript/jsbackend.h"
#include "getopts.h"

/**
  * Global parser values
  */

extern int parserlex (void);
extern int parserparse (void);

extern "C" int parserwrap (void );
extern int line_num;
extern FILE* parserin;

int parserwrap(void)
{
    return 1;
}

extern void parsererror( char* );

void parsererror( char* s )
{
    qDebug("ERROR in line %i: %s", line_num, s );
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QOptions options(argc, (const char**)argv);
    options.setProgramName("wala");
    options.setMaxNonOptionalValues(1);
    options.setMinNonOptionalValues(1);
    QOption o1( Cmd_Platform, "platform" );
    o1.setShortCode('p');
    o1.setNeedsValue( true, "wave", "arg" );
    o1.setDescription("The platform for which code should be generated. Can be 'wave', 'gadget' or 'simulation'");    
    options.addOption( o1 );
    QOption o2( Cmd_Html, "html" );
    o2.setShortCode('h');
    o2.setNeedsValue( true, QString::null, "file" );
    o2.setDescription("Generates a HTML file for running the generated javascript code");
    options.addOption( o2 );
    QOption o3( Cmd_Manifest, "manifest" );
    o3.setShortCode('m');
    o3.setNeedsValue( true, QString::null, "file" );
    o3.setDescription("Generates a XML manifest for a Google Wave gadget for running the generated javascript code as a gadget");
    options.addOption( o3 );
    QOption o4( Cmd_UrlPrefix, "urlprefix" );
    o4.setShortCode('u');
    o4.setNeedsValue( true, QString::null, "urlprefix" );
    o4.setDescription("A prefix for the URL such as http://my.project.com/somedir/. It must end with a slash");
    options.addOption( o4 );

    QTextStream out( stdout );
    if ( !options.parse() )
    {
        options.printError(out);
        return 1;
    }
    if ( options.nonOptionValues().count() == 0 )
    {
        options.printHelp(out);
        return 1;
    }

    Parser parser(options);
    if ( ErrorLog::hasErrors() )
    {
        out << ErrorLog::output() << endl;
        return 1;
    }

    QByteArray infile = options.nonOptionValues()[0].toLocal8Bit();
    parserin = fopen( infile.constData(), "r" );
    parserparse();

    parser.resolveAll();

    if ( !ErrorLog::hasErrors() )
    {
        if ( !parser.mainTemplate() )
            ErrorLog::error( YYLTYPE(), "No 'main' template has been defined" );
    }

    if ( !ErrorLog::hasErrors() )
    {
        JSBackend backend(&options);
        backend.run();
        backend.finish();
    }

    if ( ErrorLog::isEmpty() )
    {
        out << "Compile completed successfully" << endl;
        return 0;
    }

    if ( !ErrorLog::hasErrors() )
    {
        out << ErrorLog::output() << endl;
        return 0;
    }

    out << ErrorLog::output() << endl;
    return 1;
}
